/**
 * 
 */
package com.module.hq.ui.mono.heroviewer.widgets;

import com.dalonedrau.jogl.engine.GlobalConsts;
import com.dalonedrau.jogl.engine.JOGLErrorHandler;
import com.dalonedrau.jogl.opengl.sprite.BasicSpriteObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteBase;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObject;
import com.dalonedrau.jogl.opengl.sprite.SpriteImageObjectFactory;
import com.dalonedrau.jogl.opengl.ui.Label;
import com.dalonedrau.jogl.opengl.ui.UIFactory;
import com.dalonedrau.jogl.opengl.ui.border.Abstract8ImageNoBackgroundBorder;
import com.dalonedrau.jogl.opengl.ui.border.StatsBorder;
import com.dalonedrau.jogl.opengl.ui.panel.LandscapePagePanel;
import com.dalonedrau.jogl.opengl.ui.panel.Panel;
import com.dalonedrau.jogl.opengl.ui.panel.PortraitPagePanel;
import com.dalonedrau.pool.PooledStringBuilder;
import com.dalonedrau.pool.StringBuilderPool;
import com.module.hq.bus.globals.HQGlobals;
import com.module.hq.engine.HQCharacter;

/**
 * @author Donald
 */
public final class StatsPanel extends PortraitPagePanel {
	/** the singleton instance of {@link StatsPanel}. */
	private static StatsPanel	instance;
	/**
	 * Gets the one and only instance of {@link StatsPanel}.
	 * @return {@link StatsPanel}
	 */
	public static StatsPanel getInstance() {
		if (StatsPanel.instance == null) {
			StatsPanel.instance = new StatsPanel();
		}
		return StatsPanel.instance;
	}
	/** the panel for the ATTACK bar. */
	private Panel	pnlATT;
	/** the panel for the BODY bar. */
	private Panel	pnlBDY;
	/** the panel for the DEFEND bar. */
	private Panel	pnlDEF;
	/** the panel for the MIND bar. */
	private Panel	pnlMND;
	/** the panel for the MOVEMENT bar. */
	private Panel	pnlMOV;
	/** the ATTACK stat bar. */
	private StatBar	sbATT;
	/** the BODY stat bar. */
	private StatBar	sbBDY;
	/** the DEFEND stat bar. */
	private StatBar	sbDEF;
	/** the MIND stat bar. */
	private StatBar	sbMND;
	/** the MOVEMENT stat bar. */
	private StatBar	sbMOV;
	/**
	 * Creates a new instance of {@link StatsPanel}.
	 */
	private StatsPanel() {
		super(Panel.PORTRAIT_CENTER);
		super.setBorder(new Abstract8ImageNoBackgroundBorder(
				new int[] { 
						GlobalConsts.INT_003, GlobalConsts.INT_003, 
						GlobalConsts.INT_003, GlobalConsts.INT_003 
						}, // insets
				HQGlobals.HQ_MONO_NAMEPANEL_REV_BORDER)
				);
		try {
			init();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * Gets a panel containing the status bar images.
	 * @return {@link Panel}
	 * @throws Exception if an error occurs
	 */
	private Panel getImageBarPanel() throws Exception {
		Panel pnl = new PortraitPagePanel(Panel.PORTRAIT_CENTER);
		// ATTACK
		pnlATT = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		sbATT = new StatBar(0, 0, GlobalConsts.INT_064, GlobalConsts.INT_006);
		sbATT.setMax(GlobalConsts.INT_010);
		getStatsImageBarRow(
				pnlATT,
				"hq_mono_icon_attack",
				sbATT// ,
		// "The fighting power of the Hero's weapon."
		);
		pnl.addChild(pnlATT);
		// DEFEND
		pnlDEF = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		sbDEF = new StatBar(0, 0, GlobalConsts.INT_064, GlobalConsts.INT_006);
		sbDEF.setMax(GlobalConsts.INT_010);
		getStatsImageBarRow(
				pnlDEF,
				"hq_mono_icon_defend",
				sbDEF// ,
		// "The ability of the Hero to dodge or absorb enemy hits."
		);
		pnl.addChild(pnlDEF);
		// BODY
		pnlBDY = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		sbBDY = new StatBar(0, 0, GlobalConsts.INT_064, GlobalConsts.INT_006);
		sbBDY.setMax(GlobalConsts.INT_010);
		getStatsImageBarRow(
				pnlBDY,
				"hq_mono_icon_body",
				sbBDY// ,
		// "The Hero's physical strength."
		);
		pnl.addChild(pnlBDY);
		// MIND
		pnlMND = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		sbMND = new StatBar(0, 0, GlobalConsts.INT_064, GlobalConsts.INT_006);
		sbMND.setMax(GlobalConsts.INT_010);
		getStatsImageBarRow(
				pnlMND,
				"hq_mono_icon_mind",
				sbMND// ,
		// "The Hero's wisdom, intelligence, and resistance to magical "
		// + "influence."
		);
		pnl.addChild(pnlMND);
		// MOVEMENT
		pnlMOV = new LandscapePagePanel(Panel.LANDSCAPE_CENTER);
		sbMOV = new StatBar(0, 0, GlobalConsts.INT_064, GlobalConsts.INT_006);
		sbMOV.setMax(GlobalConsts.INT_010);
		getStatsImageBarRow(
				pnlMOV,
				"hq_mono_icon_movement",
				sbMOV// ,
		// "The Hero's movement rate."
		);
		pnl.addChild(pnlMOV);
		return pnl;
	}
	/**
	 * Sets a panel used to display a statistic.
	 * @param pnl the panel used
	 * @param icon the statistic's icon
	 * @param sbVal the stat bar used
	 * @throws Exception is an error occurs
	 */
	private void getStatsImageBarRow(final Panel pnl, final String icon,
			final StatBar sbVal) throws Exception {
		SpriteBase sb = new BasicSpriteObject();
		SpriteImageObject img =
				SpriteImageObjectFactory.getInstance().getImageByName(icon);
		sb.setImageRefId(img.getRefId());
		sb.setWidth(img.getWidth());
		sb.setHeight(img.getHeight());
		Label label = new Label(sb);
		pnl.addChild(label);
		pnl.addChild(sbVal);
	}
	/**
	 * Gets a "stats" label for display in the viewer.
	 * @return {@link Label}
	 */
	public Label getStatsLabel() {
		final int w = 22, h = 25;
		Label lbl = UIFactory.getInstance().getStandardH2Label("");
		lbl.setMaximumSize(w, h);
		lbl.setMinimumSize(w, h);
		lbl.setBorder(new StatsBorder());
		return lbl;
	}
	/**
	 * Initializes the view.
	 * @throws Exception if an error occurs
	 */
	private void init() throws Exception {
		super.addChild(getImageBarPanel());
	}
	/**
	 * Updates the view.
	 * @param pc the {@link HQCharacter} being viewed
	 */
	public void update(final HQCharacter pc) {
		// check for apostrophe
		PooledStringBuilder sb =
			StringBuilderPool.getInstance().getStringBuilder();
		boolean needsApos = false;
		sb.append(pc.getName());
		if (sb.toString().charAt(sb.length() - 1) == 's'
				|| sb.toString().charAt(sb.length() - 1) == 'x'
				|| sb.toString().charAt(sb.length() - 1) == 'z') {
			needsApos = true;
		}
		sb.setLength(0);
		// ATTACK
		if (pc.getFullAttack() == -GlobalConsts.INT_999) {
			sbATT.setCurrent(0);
			pnlATT.setTooltipText("");
		} else {
			sbATT.setCurrent(pc.getFullAttack());
			sb.append("The fighting power of the hero's weapon.\n");
			sb.append(pc.getName());
			if (needsApos) {
				sb.append("' weapon gives him an ATTACK rating of ");
			} else {
				sb.append("'s weapon gives him an ATTACK rating of ");
			}
			sb.append((int) pc.getFullAttack());
			sb.append(".");
			pnlATT.setTooltipText(sb.toString());
			sb.setLength(0);
		}
		// DEFEND
		if (pc.getFullDefend() == -GlobalConsts.INT_999) {
			sbDEF.setCurrent(0);
			pnlDEF.setTooltipText("");
		} else {
			sbDEF.setCurrent(pc.getFullDefend());
			sb.append("The ability of the hero to dodge or absorb enemy ");
			sb.append("hits.\n");
			sb.append(pc.getName());
			if (needsApos) {
				sb.append("' defensive bonus is ");
			} else {
				sb.append("'s defensive bonus is ");
			}
			sb.append((int) pc.getFullDefend());
			sb.append(".");
			pnlDEF.setTooltipText(sb.toString());
			sb.setLength(0);
		}
		// BODY
		if (pc.getFullBody() == -GlobalConsts.INT_999) {
			sbBDY.setCurrent(0);
			pnlBDY.setTooltipText("");
		} else {
			sbBDY.setCurrent(pc.getFullBody());
			sb.append("The hero's physical strengh, and the amount of damage ");
			sb.append("he can take before death.\n");
			sb.append(pc.getName());
			if (needsApos) {
				sb.append("' BODY POINTS are ");
			} else {
				sb.append("'s BODY POINTS are ");
			}
			sb.append((int) pc.getFullBody());
			sb.append("/");
			sb.append((int) pc.getFullMaxBody());
			sb.append(".");
			pnlBDY.setTooltipText(sb.toString());
			sb.setLength(0);
		}
		// MIND
		if (pc.getFullMind() == -GlobalConsts.INT_999) {
			sbMND.setCurrent(0);
			pnlMND.setTooltipText("");
		} else {
			sbMND.setCurrent(pc.getFullMind());
			sb.append("The hero's wisdom, intelligence, and resistance to ");
			sb.append("magical influence. If MIND POINTS ever reach 0, the ");
			sb.append("hero will die.\n");
			sb.append(pc.getName());
			if (needsApos) {
				sb.append("' MIND POINTS are ");
			} else {
				sb.append("'s MIND POINTS are ");
			}
			sb.append((int) pc.getFullMind());
			sb.append("/");
			sb.append((int) pc.getFullMaxMind());
			sb.append(".");
			pnlMND.setTooltipText(sb.toString());
			sb.setLength(0);
		}
		// MOVEMENT
		if (pc.getFullMovement() == -GlobalConsts.INT_999) {
			sbMOV.setCurrent(0);
			pnlMOV.setTooltipText("");
		} else {
			sbMOV.setCurrent(pc.getFullMovement());
			sb.append("The Hero's movement rate.\n");
			sb.append(pc.getName());
			if (needsApos) {
				sb.append("' MOVEMENT RATE is ");
			} else {
				sb.append("'s MOVEMENT RATE is ");
			}
			sb.append((int) pc.getFullMovement());
			sb.append(".");
			pnlMOV.setTooltipText(sb.toString());
			sb.setLength(0);
		}
		sb.returnToPool();
	}
}
